package prome

import (
	"errors"
	"fmt"
	"log"
	"net"
	"net/http"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

type Exporter struct {
	port int
	li   net.Listener
}

var latencyGauge = prometheus.NewGaugeVec(
	prometheus.GaugeOpts{
		Name: "node_network_latency_ms",
		Help: "Latency between cluster nodes in ms",
	},
	[]string{"src", "dst"},
)

func NewExporter(port int) *Exporter {
	prometheus.MustRegister(latencyGauge)
	return &Exporter{
		port: port,
	}
}

func (e *Exporter) Start() error {
	addr := fmt.Sprintf(":%d", e.port)
	li, err := net.Listen("tcp", addr)
	if err != nil {
		return fmt.Errorf("failed to listen on %s: %v", addr, err)
	}
	e.li = li

	http.Handle("/metrics", promhttp.Handler())
	server := &http.Server{}

	go func() {
		if err := server.Serve(e.li); err != nil && !errors.Is(err, http.ErrServerClosed) {
			log.Fatalf("HTTP server ListenAndServe: %v", err)
		}
	}()

	log.Printf("Prometheus exporter started on %s", addr)
	return nil
}

func (e *Exporter) Stop() error {
	if e.li != nil {
		return e.li.Close()
	}
	return nil
}

// UpdateLatency 更新节点间的延迟指标
func (e *Exporter) UpdateLatency(srcNode, dstNode string, latencyMs float64) {
	latencyGauge.WithLabelValues(srcNode, dstNode).Set(latencyMs)
}
